import { Button, Tabs } from 'antd';
import React, { useCallback, useEffect, useState, ReactElement, Fragment } from 'react';
import { dayRegex, hourRegex, minuteRegex, monthRegex, secondRegex, weekRegex, yearRegex } from './cron-regex';

import DayPane from './DayPane';
import HourPane from './HourPane';
import MinutePane from './MinutePane';
import MonthPane from './MonthPane';
import SecondPane from './SecondPane';
import WeekPane from './WeekPane';
import YearPane from './YearPane';

const { TabPane } = Tabs;
const tabPaneStyle = { paddingLeft: 10, paddingBottom: 8, marginTop: -10 };
const getTabTitle = (text: any) => <div style={{ width: 50, textAlign: 'center' }}>{text}</div>;

interface Props {
    defaultTab?: string
    style?: Partial<Record<string, string>>;
    footerStyle?: Partial<Record<string, string>>;
    footerRenderer?: (onReset: () => void, onGenerate: () => void) => React.ReactNode;
    value?: string
    onOk?: (v: string) => void
}


export default function Cron(props: Props): ReactElement {
    const { defaultTab, style, footerStyle, footerRenderer, value, onOk } = props;
    const [currentTab, setCurrentTab] = useState('second');
    const [second, setSecond] = useState('*');
    const [minute, setMinute] = useState('*');
    const [hour, setHour] = useState('*');
    const [day, setDay] = useState('*');
    const [month, setMonth] = useState('*');
    const [week, setWeek] = useState('?');
    const [year, setYear] = useState('*');

    useEffect(() => {
        if (defaultTab) {
            setCurrentTab(defaultTab)
        }
    }, [defaultTab])

    const onParse = () => {
        return new Promise((resolve) => {
            if (value) {
                try {
                    let [secondVal, minuteValue, hourVal, dayVal, monthVal, weekVal, yearVal] = value.split(" ");
                    secondVal = secondRegex.test(secondVal) ? secondVal : "*";
                    minuteValue = minuteRegex.test(minuteValue) ? minuteValue : "*";
                    hourVal = hourRegex.test(hourVal) ? hourVal : "*";
                    dayVal = dayRegex.test(dayVal) ? dayVal : "*";
                    monthVal = monthRegex.test(monthVal) ? monthVal : "*";
                    weekVal = weekRegex.test(weekVal) ? weekVal : "?";
                    weekVal = dayVal !== "?" ? "?" : weekVal;
                    yearVal = yearRegex.test(yearVal) ? yearVal : "*";
                    setSecond(secondVal);
                    setMinute(minuteValue);
                    setHour(hourVal);
                    setDay(dayVal);
                    setMonth(monthVal);
                    setWeek(weekVal);
                    setYear(yearVal);
                    resolve({
                        value,
                        secondVal,
                        minuteValue,
                        hourVal,
                        dayVal,
                        monthVal,
                        weekVal,
                        yearVal,
                    });
                } catch (error) {
                    setSecond("*");
                    setMinute("*");
                    setHour("*");
                    setDay("*");
                    setMonth("*");
                    setWeek("?");
                    setYear("*");
                    resolve({});
                }
            } else {
                setSecond("*");
                setMinute("*");
                setHour("*");
                setDay("*");
                setMonth("*");
                setWeek("?");
                setYear("*");
                resolve({});
            }
        });
    };

    const onReset = () => {
        setSecond('*');
        setMinute('*');
        setHour('*');
        setDay('*');
        setMonth('*');
        setWeek('?');
        setYear('*');
        if (onOk) {
            onOk(['*', '*', '*', '*', '*', '?', '*'].join(' '));
        }
    };

    const onGenerate = () => {
        if (onOk) {
            onOk([second, minute, hour, day, month, week, year].join(" "));
        }
    };

    const onChangeDay = (v: string) => {
        setDay(v);
        if (v !== "?") {
            setWeek("?");
        }
    };

    const onChangeWeek = (v: string) => {
        setWeek(v);
        if (v !== "?") {
            setDay("?");
        }
    };

    useEffect(() => {
        onParse();
    }, [value]);

    const footerRendererWrapper = useCallback(() => {
        if (footerRenderer && typeof footerRenderer === 'function') {
            return footerRenderer(onReset, onGenerate);
        }
        return (
            <Fragment>
                <Button style={{ marginRight: 10 }} onClick={onReset}>
                    重置
                </Button>
                <Button type="primary" onClick={onGenerate}>
                    生成
                </Button>
            </Fragment>
        );
    }, [footerRenderer, onReset, onGenerate]);

    return (
        <div
            style={{
                backgroundColor: '#fff',
                borderRadius: '2px',
                outline: 'none',
                boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)',
                width: 600,
                ...style,
            }}
        >
            {/* destroyInactiveTabPane */}
            <Tabs tabBarGutter={0} animated={false} activeKey={currentTab} onChange={setCurrentTab}>
                <TabPane tab={getTabTitle('秒')} key="second" style={tabPaneStyle}>
                    <SecondPane value={second} onChange={setSecond} />
                </TabPane>
                <TabPane tab={getTabTitle('分')} key="minute" style={tabPaneStyle}>
                    <MinutePane value={minute} onChange={setMinute} />
                </TabPane>
                <TabPane tab={getTabTitle('时')} key="hour" style={tabPaneStyle}>
                    <HourPane value={hour} onChange={setHour} />
                </TabPane>
                <TabPane tab={getTabTitle('日')} key="day" style={tabPaneStyle}>
                    <DayPane value={day} onChange={onChangeDay} />
                </TabPane>
                <TabPane tab={getTabTitle('月')} key="month" style={tabPaneStyle}>
                    <MonthPane value={month} onChange={setMonth} />
                </TabPane>
                <TabPane tab={getTabTitle('周')} key="week" style={tabPaneStyle}>
                    <WeekPane value={week} onChange={onChangeWeek} />
                </TabPane>
                <TabPane tab={getTabTitle('年')} key="year" style={tabPaneStyle}>
                    <YearPane value={year} onChange={setYear} />
                </TabPane>
            </Tabs>
            <div style={{ borderTop: '1px solid #e8e8e8', padding: 10, textAlign: 'right', ...footerStyle }}>
                {footerRendererWrapper()}
            </div>
        </div>
    );
}